package serv

import (
	"encoding/json"
	"erp/model"
	"erp/utils"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
)

// func GoodsIndexCtrl(c *gin.Context) {
// 	userData, _ := c.Get("userData")

// 	log.Println("------", userData)
// 	c.HTML(http.StatusOK, "clothes-index.html", nil)
// }

func AdminGoodsListCtrl(c *gin.Context) {
	if c.Request.Method == "POST" {

		postData := GetJsonData(c)
		cate_id := utils.Intval(postData["cate_id"])
		名称 := utils.Strval(postData["名称"])
		limit := utils.Intval(postData["limit"])
		start := (utils.Intval(postData["page"]) - 1) * limit

		if limit < 1 {
			limit = 10
		}

		t := dbEngine.Table("f_shop_goods")
		t1 := dbEngine.Table("f_shop_goods")
		if cate_id != 0 {
			t.Where("cate_id=?", cate_id)
			t1.Where("cate_id=?", cate_id)
		}

		if 名称 != "" {
			t.Where("goods_name like ?", "%"+名称+"%")
			t1.Where("goods_name like ?", "%"+名称+"%")
		}

		dataArr := []map[string]any{}
		t.Limit(limit, start).Find(&dataArr)

		cnt, _ := t1.Count()

		c.JSON(200, ApiList{
			Status: 200,
			Data: ApiDataListObj{
				Total:   cnt,
				PerPage: limit,
				Data:    dataArr,
			},
		})
	} else {
		c.HTML(http.StatusOK, "goods-list.html", nil)
	}
}

func AdminGoodsGetUpdateInfoCtrl(c *gin.Context) {
	param := GetJsonData(c)
	id := param["id"]

	nodeArr := map[string]any{}
	dbEngine.Table("f_shop_goods").Select("*").Where("id=?", id).Get(&nodeArr)

	c.JSON(200, map[string]any{"status": 200, "data": nodeArr})
}

func SysGetMenuCtrl(c *gin.Context) {
	userData, _ := c.Get("userData")
	config_file := "config/menu" + strconv.Itoa(userData.(model.AdminUser).RoleId) + ".json"

	data, err := os.ReadFile(config_file)
	if nil != err {
		log.Fatalln("ReadFile ERROR:", err)
		return
	} else {
		log.Println("ReadFile OK :\r\n", string(data))
	}

	var jsonArr any
	json.Unmarshal(data, &jsonArr)
	if err != nil {
		fmt.Println(err)
	}

	c.JSON(200, jsonArr)
}

func AdminGoodsSaveCtrl(c *gin.Context) {
	rowData := GetJsonData(c)
	var err error
	var msg string

	cols := utils.FArray{
		"id",
		"goods_name", "cate_id", "org_id", "brand_name",
		"goods_number", "sku", "pack",
		"goods_img", "goods_img_other", "buy_max", "content",
		"market_price", "sale_time", "shop_price", "supplier", "warn_number",
	}

	if rowData["id"] == nil {
		_, err = dbEngine.Table("f_shop_goods").Insert(rowData)
		msg = "添加成功"
	} else {
		for k, v := range rowData {
			if cols.Search(k) == -1 {
				delete(rowData, k)
			}

			// fmt.Print(k, v, reflect.TypeOf(v))

			if v == nil {
				delete(rowData, k)
			} else if strings.Contains(k, "_time") {
				if v == "" {
					delete(rowData, k)
				}
			}
		}

		fmt.Println(rowData)

		// delete(rowData, "create_time")
		_, err = dbEngine.Table("f_shop_goods").Where("id=?", rowData["id"]).Update(rowData)
		msg = "更新成功"
	}

	if err != nil {
		c.JSON(200, map[string]any{"status": 500, "msg": err.Error()})
	} else {
		c.JSON(200, map[string]any{"status": 200, "msg": msg})
	}
}

func AdminGoodsCateUpdateCtrl(c *gin.Context) {
	rowData := GetJsonData(c)
	var err error
	var msg string

	cols := utils.FArray{
		"id",
		"name",
		"parent_id",
		"type", "sort", "is_show", "summary",
	}

	if rowData["id"] == nil {
		_, err = dbEngine.Table("f_category").Insert(rowData)
		msg = "添加成功"
	} else {
		for k, v := range rowData {
			if cols.Search(k) == -1 {
				delete(rowData, k)
			}

			// fmt.Print(k, v, reflect.TypeOf(v))

			if v == nil {
				delete(rowData, k)
			} else if strings.Contains(k, "_time") {
				if v == "" {
					delete(rowData, k)
				}
			}
		}

		_, err = dbEngine.Table("f_category").Where("id=?", rowData["id"]).Update(rowData)
		msg = "更新成功"
	}

	if err != nil {
		c.JSON(200, map[string]any{"status": 500, "msg": err.Error()})
	} else {
		c.JSON(200, map[string]any{"status": 200, "msg": msg})
	}
}

func AdminGoodsCateListCtrl(c *gin.Context) {
	if c.Request.Method == "POST" {

		where := "type='goods'"

		cateArr := []map[string]any{}
		dbEngine.Table("f_category").Where(where).Find(&cateArr)

		c.JSON(200, ApiList{
			Status: 200,
			Data: ApiDataListObj{
				Total:       0,
				PerPage:     0,
				CurrentPage: 0,
				LastPage:    0,
				Data:        cateArr,
			},
		})
	} else {
		c.HTML(http.StatusOK, "goods-list.html", nil)
	}
}

func AdminGoodsGetCateCtrl(c *gin.Context) {
	param := GetJsonData(c)
	id := param["id"]

	nodeArr := map[string]any{}
	dbEngine.Table("f_category").Select("*").Where("id=?", id).Get(&nodeArr)

	c.JSON(200, map[string]any{"status": 200, "data": nodeArr})
}

func AdminGoodsDeleteCateCtrl(c *gin.Context) {}

func AdminOrderIndexCtrl(c *gin.Context) {
	rowData := GetJsonData(c)
	limit := int(rowData["limit"].(float64))
	start := (int(rowData["page"].(float64)) - 1) * limit
	org_name := utils.Strval(rowData["org_name"])
	name := utils.Strval(rowData["name"])

	createTime := rowData["create_time"]

	if limit < 1 {
		limit = 10
	}

	t := dbEngine.Table("f_shop_order")
	t1 := dbEngine.Table("f_shop_order")
	if org_name != "" {
		t.Where("org_name=?", org_name)
		t1.Where("org_name=?", org_name)
	}

	if name != "" {
		t.Where("name like ?", "%"+name+"%")
		t1.Where("name like ?", "%"+name+"%")
	}

	if createTime != nil {
		createTime1 := createTime.([]any)[0]
		createTime2 := createTime.([]any)[1]
		t.Where("create_time >= ? and create_time <=? ", createTime1.(string)+" 00:00:00", createTime2.(string)+" 23:59:59")
		t1.Where("create_time >= ? and create_time <=? ", createTime1.(string)+" 00:00:00", createTime2.(string)+" 23:59:59")
	}

	dataArr := []model.Order{}
	t.Cols("id, name, org_name, order_amount, create_time").OrderBy("id desc").Limit(limit, start).Find(&dataArr)
	cnt, _ := t1.Count()

	for index, item := range dataArr {
		items := []map[string]any{}
		dbEngine.Table("f_shop_order_goods").Cols("goods_id, goods_name,sku_name, goods_img,goods_price, buy_number").Where("order_id=?", item.Id).Find(&items)

		item.OrderGoods = items
		dataArr[index] = item
	}

	c.JSON(200, ApiList{
		Status: 200,
		Data: ApiDataListObj{
			Total:   cnt,
			PerPage: limit,
			Data:    dataArr,
		},
	})
}

func AdminOrderExportExcelCtrl(c *gin.Context) {
	rowData := GetJsonData(c)
	org_name := utils.Strval(rowData["org_name"])
	name := utils.Strval(rowData["name"])
	createTime := rowData["create_time"]

	t := dbEngine.Table("f_shop_order")
	if org_name != "" {
		t.Where("org_name=?", org_name)
	}

	if name != "" {
		t.Where("name like ?", "%"+name+"%")
	}

	if createTime != nil {
		createTime1 := createTime.([]any)[0]
		createTime2 := createTime.([]any)[1]
		t.Where("create_time >= ? and create_time <=? ", createTime1.(string)+" 00:00:00", createTime2.(string)+" 23:59:59")
	}

	dataArr := []model.Order{}
	t.Cols("id, name, org_name, order_amount, create_time").Find(&dataArr)

	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()

	// f.DeleteSheet("Sheet1")
	f.NewSheet("订单明细")
	// f.NewSheet("单位领用统计")
	// f.NewSheet("物品领用统计")

	// sheet_index, err := f.NewSheet("订单明细")
	// if err != nil {
	// 	fmt.Println(err)
	// 	return
	// }
	f.SetActiveSheet(1)
	f.SetCellValue("订单明细", "A1", "姓名")
	f.SetCellValue("订单明细", "B1", "单位")
	f.SetCellValue("订单明细", "C1", "时间")
	f.SetCellValue("订单明细", "D1", "金额")
	f.SetCellValue("订单明细", "E1", "物品")
	f.SetCellValue("订单明细", "F1", "型号")
	f.SetCellValue("订单明细", "G1", "物品单价")
	f.SetCellValue("订单明细", "H1", "领取数量")

	row_index := 1
	for _, item := range dataArr {
		row_index += 1

		f.SetCellValue("订单明细", "A"+strconv.Itoa(row_index), item.Name)
		f.SetCellValue("订单明细", "B"+strconv.Itoa(row_index), item.OrgName)
		f.SetCellValue("订单明细", "C"+strconv.Itoa(row_index), item.CreateTime)
		f.SetCellValue("订单明细", "D"+strconv.Itoa(row_index), item.OrderAmount)

		goodsItems := []map[string]any{}
		dbEngine.Table("f_shop_order_goods").Cols("goods_id,sku_name, goods_name, goods_img,goods_price, buy_number").Where("order_id=?", item.Id).Find(&goodsItems)

		for _, goodsItem := range goodsItems {
			f.SetCellValue("订单明细", "E"+strconv.Itoa(row_index), goodsItem["goods_name"])
			f.SetCellValue("订单明细", "F"+strconv.Itoa(row_index), goodsItem["sku_name"])
			f.SetCellValue("订单明细", "G"+strconv.Itoa(row_index), goodsItem["goods_price"])
			f.SetCellValue("订单明细", "H"+strconv.Itoa(row_index), goodsItem["buy_number"])
		}
	}

	buffer, _ := f.WriteToBuffer()
	c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
	c.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(createFileName()))
	_, _ = c.Writer.Write(buffer.Bytes())
}

func AdminOrderExportExcel1Ctrl(c *gin.Context) {
	rowData := GetJsonData(c)
	org_name := utils.Strval(rowData["org_name"])
	name := utils.Strval(rowData["name"])
	createTime := rowData["create_time"]

	t := dbEngine.Table("f_shop_order_goods")
	if org_name != "" {
		t.Where("org_name=?", org_name)
	}

	if name != "" {
		t.Where("name like ?", "%"+name+"%")
	}

	if createTime != nil {
		createTime1 := createTime.([]any)[0]
		createTime2 := createTime.([]any)[1]
		t.Where("create_time >= ? and create_time <=? ", createTime1.(string)+" 00:00:00", createTime2.(string)+" 23:59:59")
	}

	dataArr := []map[string]any{}
	t.Select("goods_name, sku_name, SUM(`buy_number`) as cnt").GroupBy("goods_name, sku_name").Find(&dataArr)

	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()

	f.NewSheet("Sheet1")

	f.SetActiveSheet(1)
	f.SetCellValue("Sheet1", "A1", "名称")
	f.SetCellValue("Sheet1", "B1", "型号")
	f.SetCellValue("Sheet1", "C1", "数量")

	row_index := 1
	for _, item := range dataArr {
		row_index += 1

		f.SetCellValue("Sheet1", "A"+strconv.Itoa(row_index), item["goods_name"])
		f.SetCellValue("Sheet1", "B"+strconv.Itoa(row_index), item["sku_name"])
		f.SetCellValue("Sheet1", "C"+strconv.Itoa(row_index), item["cnt"])
	}

	buffer, _ := f.WriteToBuffer()
	c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
	c.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(createFileName()))
	_, _ = c.Writer.Write(buffer.Bytes())
}

func createFileName() string {
	name := time.Now().Format("2006-01-02-15-04-05")
	rand.Seed(time.Now().UnixNano())
	return fmt.Sprintf("订单导出-%v-%v.xlsx", name, rand.Int63n(time.Now().Unix()))
}
